package com.czkevin.wusan.tasks;

import com.czkevin.cif.CIFItemInstance;
import com.czkevin.cif.CustomItemFramework;
import com.czkevin.cif.ItemRegister;
import com.czkevin.wusan.items.*;
import com.google.common.collect.Sets;
import de.tr7zw.nbtapi.NBTCompound;
import de.tr7zw.nbtapi.NBTEntity;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;

import java.util.*;

public class WuSanExplodeCheckTask implements Runnable {
    private static final Set<Material> REDSTONE_TYPES = Collections.unmodifiableSet(Sets.newHashSet(
        Material.REDSTONE,
        Material.REDSTONE_WIRE,
        Material.REDSTONE_BLOCK,
        Material.REDSTONE_ORE,
        Material.REPEATER,
        Material.REDSTONE_TORCH,
        Material.REDSTONE_WALL_TORCH,
        Material.COMPARATOR
    ));
    private static final List<Class<? extends Entity>> ANIMAL_TYPES = Collections.unmodifiableList(Arrays.asList(
        Cow.class, Sheep.class, Chicken.class, Wolf.class, Bee.class, Donkey.class, Horse.class
    ));

    private static final Random RANDOM = new Random();

    @Override
    public void run() {
        Bukkit.getWorlds().forEach(w -> {
            w.getEntitiesByClass(Item.class).forEach(e -> proccess(w, e));
        });
    }

    private static final int RANGE_VERT = 2;
    private static final int RANGE_HORI = 4;

    private void proccess(World w, Item item) {
        NBTCompound nbt = new NBTEntity(item).getPersistentDataContainer();
        if(!nbt.hasKey(BaseWuSanItem.NBT_THROWN_WUSAN) || !nbt.getBoolean(BaseWuSanItem.NBT_THROWN_WUSAN)) return;
        if(!nbt.hasKey(BaseWuSanItem.NBT_THROWN_TIMESTAMP)) return;

        final long thrownTimestamp = nbt.getLong(BaseWuSanItem.NBT_THROWN_TIMESTAMP);
        if(System.currentTimeMillis() - thrownTimestamp < 3000L) return;

        nbt.removeKey(BaseWuSanItem.NBT_THROWN_WUSAN);

        ItemStack stack = item.getItemStack();
        CIFItemInstance instance = CustomItemFramework.getCIFDataFromItem(stack);
        if(instance == null || instance.type == null || !BaseWuSanItem.class.isAssignableFrom(instance.type.getClass())) return;

        Location location = item.getLocation();
        item.remove();

        w.spawnParticle(Particle.EXPLOSION_HUGE, location, 3);
        w.playSound(location, Sound.ENTITY_DRAGON_FIREBALL_EXPLODE, 2.0f, 1.2f);
        w.playSound(location, Sound.ENTITY_DRAGON_FIREBALL_EXPLODE, .6f, 0.6f);
        w.playSound(location, Sound.ENTITY_DRAGON_FIREBALL_EXPLODE, .4f, 0.4f);

        final boolean ripped = ((BaseWuSanItem) instance.type).isAnswersRipped(instance.data);
        if(WuSanMath.class.isAssignableFrom(instance.type.getClass())) {
            // 数学
            final int rangeVert = ripped ? RANGE_VERT * 2 : RANGE_VERT;
            final int rangeHori = ripped ? RANGE_HORI * 2 : RANGE_HORI;
            Location iterate = location.clone();
            for(int x = -rangeHori; x <= rangeHori; x++) {
                for(int y = -rangeVert; y <= rangeVert; y++) {
                    for(int z = -rangeHori; z <= rangeHori; z++) {
                        iterate.setX(location.getBlockX() + x);
                        iterate.setY(location.getBlockY() + y);
                        iterate.setZ(location.getBlockZ() + z);
                        if(!iterate.getChunk().isLoaded()) continue;
                        Block b = iterate.getBlock();
                        if(REDSTONE_TYPES.contains(b.getType())) {
                            b.setType(Material.AIR);
                        }
                    }
                }
            }
        } else if(WuSanBiology.class.isAssignableFrom(instance.type.getClass())) {
            // 生物
            final int count = ripped ? 10 : 5;
            final double horizontal_random_max = ripped ? 0.5d : 0.3d;
            final double vert_rand_max = ripped ? 1.2d : 0.6d;
            for(int i = 0; i < count; i++) {
                Vector vel = new Vector(RANDOM.nextDouble() * horizontal_random_max, 0.6d + RANDOM.nextDouble()*vert_rand_max, RANDOM.nextDouble() * horizontal_random_max);
                w.spawn(location, ANIMAL_TYPES.get(RANDOM.nextInt(ANIMAL_TYPES.size())), (spawned) -> {
                    spawned.setVelocity(vel);
                });
            }
        } else if (WuSanChinese.class.isAssignableFrom(instance.type.getClass())) {
            // 语文
        }
    }
}
